package com.besall.allbase.common.utils;

import static bb.lanxing.manager.SPConstant.TIME_UN_AUTO_SYNC;
import static com.besall.allbase.bluetooth.service.Protocol.ProtocolConstants.INFO_Set_Device_Time;
import static com.besall.allbase.bluetooth.service.Protocol.ProtocolConstants.KEY_LUSHU_FILE_ID;
import static com.besall.allbase.bluetooth.service.Protocol.ProtocolConstants.KEY_WORKOUT_LIST_FILE_ID;
import static com.besall.allbase.bluetooth.service.Protocol.ProtocolConstants.SYSTEM_TRANS_LUSHU_FILE;
import static com.besall.allbase.bluetooth.service.Protocol.ProtocolConstants.SYSTEM_TRANS_WORKOUT_LIST_FILE;
import static bb.lanxing.manager.SPConstant.TIME_AUTO_DEFAULT;
import static bb.lanxing.manager.SPConstant.TIME_AUTO_SYNC;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.util.Log;

import com.bes.bessdk.utils.ArrayUtil;
import com.bes.bessdk.utils.SPHelper;
import com.bes.sdk.utils.SettingsJsonUtils;
import com.besall.allbase.view.activity.chipstoollevel4.ota.otafilelist.OtaFilelistActivity;
import com.besall.allbase.view.activity.chipstoollevel4.protocol.ProtocolPresenter;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import com.nbsp.materialfilepicker.MaterialFilePicker;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.litepal.LitePal;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import bb.lanxing.App;
import bb.lanxing.activity.deeplink.DeepLinkPathConstants;
import bb.lanxing.lib.devices.sgsettingentity.gearprofile.Gear;
import bb.lanxing.lib.devices.sgsettingentity.routebook.Route;
import bb.lanxing.lib.devices.sgsettingentity.routebook.Routebooks;
import bb.lanxing.lib.devices.sgsettingentity.setting.CommonSettings;
import bb.lanxing.lib.devices.sgsettingentity.setting.Settings;
import bb.lanxing.lib.devices.sgsettingentity.userprofile.UserProfileSettings;
import bb.lanxing.lib.devices.sgsettingentity.workout.Workout;
import bb.lanxing.lib.devices.sgsettingentity.workout.Workouts;
import bb.lanxing.manager.SharedManager;
import bb.lanxing.model.database.RouteBookInfo;
import bb.lanxing.util.AppFileUtils;

public class FileUtils {
	private static final String TAG = "FileUtils";
	public static String OTA_FILE_NAME = "ota.txt";
	public static String OTA_STATIC = "ota_static";// ota 统计记表
	private static String mPath = Environment.getExternalStorageDirectory() + "/";
	private Context mContext;

	public FileUtils(Context context) {
		mContext = context;
	}

	public static void writebytetofile(String path, byte[] data) {
		File file = new File(path);
		BufferedOutputStream outStream = null;
		try {
			outStream = new BufferedOutputStream(new FileOutputStream(file, true));
			outStream.write(data);
			outStream.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != outStream) {
				try {
					outStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void writeTOfileAndActiveClear(String filename, String context) {
		Log.i("TAG", "writeTOfileAndActiveClear: ------" + context);
		String pkgName = "bb.lanxing";
		String path = getFolderPath() + "Android/" + "data/" + pkgName + "/" + "files/";
		isExist(path);
		path = path + "OTA/";
		isExist(path);
		path = path + filename + ".txt";
		File file = new File(path);
		try {
			if (!file.exists()) {
				file.createNewFile();
			}
			FileInputStream fis = new FileInputStream(file);
			long size = fis.available();
			fis.close();
			/**
			 * 当文件大小大于80MByte时，主动删除
			 */
			if (size >= 80000000) {
				file.delete();
				return;
			}

			FileOutputStream stream = new FileOutputStream(file, true);
			String temp = context + "\n";
			byte[] buf = temp.getBytes();
			stream.write(buf);
			stream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void writeTOFile(Object obj, String folderName, String fileName, String fileType) {
		Log.i("TAG", "writeTOFile: " + obj);
		String path = getFolderPath() + "Android/" + "data/" + ActivityUtils.getPackageName() + "/" + "files/";
		isExist(path);
		path = path + folderName + "/";
		isExist(path);
		path = path + fileName + "." + fileType;
		File file = new File(path);
		Log.i("TAG", "writeTOFile: path" + path);
		try {
			if (!file.exists()) {
				file.createNewFile();
			}
			FileInputStream fis = new FileInputStream(file);
			long size = fis.available();
			fis.close();
			/**
			 * 当文件大小大于80MByte时，主动删除
			 */
			if (size >= 80000000) {
				file.delete();
				return;
			}

			FileOutputStream stream = new FileOutputStream(file, true);

			if (obj.getClass() == String.class) {
				String temp = obj + "\n";
				byte[] buf = temp.getBytes();
				stream.write(buf);
				stream.close();
			} else if (obj.getClass() == byte[].class) {
				byte[] buf = (byte[]) obj;
				stream.write(buf);
				stream.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void writeTOFileNew(Object obj, String folderName, String fileName, String fileType, boolean firstcall) {
		// Log.i("TAG", "writeTOFile: "+ obj);
		String path = getFolderPath() + "Android/" + "data/" + ActivityUtils.getPackageName() + "/" + "files/";
		isExist(path);
		path = path + folderName + "/";
		isExist(path);
		path = path + fileName + "." + fileType;
		File file = new File(path);
		Log.i("TAG", "writeTOFile: path" + path);
		try {
			if (firstcall == true) {
				file.delete();
				// return;
			}
			if (!file.exists()) {
				file.createNewFile();
			}
			/*
			 * FileInputStream fis = new FileInputStream(file); long size = fis.available(); fis.close(); /**
			 * 当文件大小大于80MByte时，主动删除
			 */
			/*
			 * if (size >= 80000000) { file.delete(); return; }
			 */

			FileOutputStream stream = new FileOutputStream(file, true);

			if (obj.getClass() == String.class) {
				String temp = (String) obj;
				byte[] buf = temp.getBytes("UTF-8");
				stream.write(buf);
				stream.flush();
				stream.close();
			} else if (obj.getClass() == byte[].class) {
				byte[] buf = (byte[]) obj;
				stream.write(buf);
				stream.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static String getFolderPath() {
		String pathString = mPath;
		isExist(pathString);
		pathString += "/";
		return pathString;
	}

	public static void isExist(String path) {
		File file = new File(path);
		// 判断文件夹是否存在,如果不存在则创建文件夹
		if (!file.exists()) {
			synchronized (FileUtils.class) {
				file.mkdirs();
			}
		}
	}

	public static void writeArrayListTOFile(ArrayList tArrayList, String folderName, String fileName, String fileType) {
		String path = getFolderPath() + "Android/" + "data/" + ActivityUtils.getPackageName() + "/" + "files/";
		isExist(path);
		path = path + folderName + "/";
		isExist(path);
		path = path + fileName;
		File file = new File(path);
		FileOutputStream fileOutputStream = null;
		ObjectOutputStream objectOutputStream = null;
		try {
			fileOutputStream = new FileOutputStream(file); // 新建一个内容为空的文件
			objectOutputStream = new ObjectOutputStream(fileOutputStream);
			objectOutputStream.writeObject(tArrayList);
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (objectOutputStream != null) {
			try {
				objectOutputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileOutputStream != null) {
			try {
				fileOutputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static String cutLastSegmentOfPath(String path) {
		return path.substring(0, path.lastIndexOf("/"));
	}

	public static void fileToHex(Activity activity, int requestCode) {
		// (boolean) SPHelper.getPreference(activity,BES_KEY_USE_INTERNAL_FILE_ACCESS, BES_USE_INTERNAL_FILE_ACCESS);
		boolean internalFileAccess = true;
		Log.d(TAG, "wangsm_bes, fileToHex:  internalFileAccess= " + internalFileAccess);
		// internalFileAccess = true;
		if (internalFileAccess) {
			Intent intent = new Intent();
			ActivityUtils.gotoActForResult(intent, requestCode, activity, OtaFilelistActivity.class);
			return;
		}
		new MaterialFilePicker().withActivity(activity).withCloseMenu(true)
			// Entry point path (user will start from it)
			// .withPath(alarmsFolder.absolutePath)
			// Root path (user won't be able to come higher than it)
			// .withRootPath(externalStorage.absolutePath)
			// Showing hidden files
			.withHiddenFiles(true)
			// Want to choose only jpg images
			// .withFilter(Pattern.compile(".*\\.(hex|Hex)$"))
			// Don't apply filter to directories names
			.withFilterDirectories(false)
			// .withTitle("choose bin")
			.withRequestCode(requestCode)// 必须添加
			.start();
	}

	/* parse the personal settings to settings.json item */
	public static String createCommonSettingsJsonStr(CommonSettings commonSettings) {
		// JSONArray jsonArray = new JSONArray();

		try {
			JSONObject settingsAllJson = new JSONObject();
			Settings settings = commonSettings.getSettings();
			settingsAllJson.put("version", settings.getVersion());
			settingsAllJson.put("device_model", commonSettings.getDevice_model());
			settingsAllJson.put("sn", commonSettings.getSn());
			settingsAllJson.put("update_at", commonSettings.getUpdated_at());
			settingsAllJson.put("language", settings.getLanguage());
			settingsAllJson.put("unit", settings.getUnit());
			settingsAllJson.put("temperature_unit", settings.getTemperature_unit());
			settingsAllJson.put("time_formatter", settings.getTime_formatter());
			settingsAllJson.put("screen_on_mode", settings.getBacklight());
			settingsAllJson.put("auto_pause", settings.getAuto_pause());
			settingsAllJson.put("overwrite", settings.getOverwrite());
			settingsAllJson.put("keytone", settings.getKeytone());
			settingsAllJson.put("settings_reset", settings.getSettings_reset());
			settingsAllJson.put("factory_reset", settings.getFactory_reset());

			/*
			 * JSONObject settingJson = new JSONObject(); Settings settings = commonSettings.getSettings();
			 * settingJson.put("language",settings.getLanguage_i18n()); settingJson.put("unit",settings.getUnit());
			 * settingJson.put("temperature_unit",settings.getTemperature_unit());
			 * settingJson.put("time_formatter",settings.getTime_formatter());
			 * settingJson.put("screen_on_mode",settings.getBacklight());
			 * settingJson.put("auto_pause",settings.getAuto_pause());
			 * settingJson.put("overwrite",settings.getOverwrite()); settingJson.put("keytone",settings.getKeytone());
			 * settingsAllJson.put("settings",settingJson);
			 */

			String jsonString = settingsAllJson.toString();
			Log.d(TAG, "wangsm_bes, test the json str: " + jsonString);
			return jsonString;
			// jsonArray.put(settingsAllJson);
			// jsonArray.put(personalObj);
			// String jsonStr = jsonArray.toString();
			// bb.lanxing.util.Log.d(TAG,"wangsm_bes, test the jsonArray str: "+ jsonArray.toString());
		} catch (JSONException e) {
			throw new RuntimeException(e);
		}
	}

	/*
	 * public static String createSettingsJsonStr(PersonalSettings personalSettings){ // JSONArray jsonArray = new
	 * JSONArray();
	 *
	 * try { JSONObject settingsAllJson = new JSONObject();
	 * settingsAllJson.put("version",personalSettings.getVersion());
	 * settingsAllJson.put("device_model",personalSettings.getDevice_model());
	 * settingsAllJson.put("sn",personalSettings.getSn());
	 * settingsAllJson.put("update_at",personalSettings.getUpdate_at());
	 *
	 * JSONObject settingJson = new JSONObject(); settingJson.put("language",personalSettings.getLanguage_str());
	 * settingJson.put("unit",personalSettings.getUnit());
	 * settingJson.put("temperature_unit",personalSettings.getTemperatureUnit());
	 * settingJson.put("time_formatter",personalSettings.getTimeFormatter());
	 * settingJson.put("screen_on_mode",personalSettings.getBacklight());
	 * settingJson.put("auto_pause",personalSettings.getAutoPauseInt());
	 * settingJson.put("overwrite",personalSettings.getOverWrite());
	 * settingJson.put("keytone",personalSettings.isKeyTone()); settingsAllJson.put("settings",settingJson); String
	 * jsonString = settingsAllJson.toString(); bb.lanxing.util.Log.d(TAG,"wangsm_bes, test the json str: "+
	 * jsonString); return jsonString; // jsonArray.put(settingsAllJson); // jsonArray.put(personalObj); // String
	 * jsonStr = jsonArray.toString(); // bb.lanxing.util.Log.d(TAG,"wangsm_bes, test the jsonArray str: "+
	 * jsonArray.toString()); } catch (JSONException e) { throw new RuntimeException(e); } }
	 */
	/* parse the personal settings to user_profile.json item */
	public static String createUserProfileSettingsJsonStr(UserProfileSettings userProfileSettings) {
		// JSONArray jsonArray = new JSONArray();
		if (userProfileSettings == null) {
			Log.d(TAG, "the user profile settings is null,return");
			return null;
		}
		// UserProfile userProfile = userProfileSettings.getUser_profile();
		try {
			JSONObject userProfileAllJson = new JSONObject();
			userProfileAllJson.put("version", userProfileSettings.getVersion());
			userProfileAllJson.put("device_model", userProfileSettings.getDevice_model());
			userProfileAllJson.put("sn", userProfileSettings.getSn());
			userProfileAllJson.put("update_at", userProfileSettings.getUpdate_at());
			// User
			userProfileAllJson.put("platform", "Bes");// this is from db
			userProfileAllJson.put("uid", userProfileSettings.getUid());// this is from db
			userProfileAllJson.put("user_name", userProfileSettings.getUser_name());// this is from db
			// userProfile
			userProfileAllJson.put("ALAHR", userProfileSettings.getALAHR());// userProfile
			userProfileAllJson.put("ALASPEED", userProfileSettings.getALASPEED());
			userProfileAllJson.put("FTP", userProfileSettings.getFTP());
			userProfileAllJson.put("LTHR", userProfileSettings.getLTHR());
			userProfileAllJson.put("MAXHR", userProfileSettings.getMAXHR());
			Log.d(TAG, "birthday second: " + userProfileSettings.getBirthday());
			userProfileAllJson.put("birthday", userProfileSettings.getBirthday());// 130417154
			userProfileAllJson.put("age", userProfileSettings.getAge());
			userProfileAllJson.put("gender", userProfileSettings.getGender());
			userProfileAllJson.put("height", userProfileSettings.getHeight());
			userProfileAllJson.put("weight", userProfileSettings.getWeight());
			userProfileAllJson.put("time_zone", userProfileSettings.getTime_zone());// 28800

			/*
			 * //user JSONObject userJson = new JSONObject(); userJson.put("platform","Bes");//this is from db
			 * userJson.put("uid",6977967);//this is from db userJson.put("user_name","18688888888");//this is from db
			 * userProfileAllJson.put("user",userJson); //user_profile JSONObject userProfileJson = new JSONObject();
			 * userProfileJson.put("ALAHR",160); userProfileJson.put("ALASPEED",1389); userProfileJson.put("FTP",160);
			 * userProfileJson.put("LTHR",160); userProfileJson.put("MAXHR",196);
			 * userProfileJson.put("birthday",130417154); userProfileJson.put("gender",1);
			 * userProfileJson.put("height",1800); userProfileJson.put("time_zone",28800);
			 * userProfileJson.put("weight",65000); userProfileAllJson.put("user_profile",userProfileJson);
			 */

			String userProfilejsonString = userProfileAllJson.toString();
			bb.lanxing.util.Log.i("wangsm_bes,  the user_profile json str: " + userProfilejsonString);
			return userProfilejsonString;
		} catch (JSONException e) {
			throw new RuntimeException(e);
		}
	}

	public static String createGearProfileJsonStr(CommonSettings commonSettings, List<Gear> gearList) {
		JSONArray jsonArray = new JSONArray();
		if (commonSettings == null) {
			Log.d(TAG, "the common settings is null,return");
			return null;
		}

		try {
			JSONObject userProfileAllJson = new JSONObject();
			Settings settings = commonSettings.getSettings();
			userProfileAllJson.put("version", settings.getVersion());
			userProfileAllJson.put("device_model", commonSettings.getDevice_model());
			userProfileAllJson.put("sn", commonSettings.getSn());
			userProfileAllJson.put("update_at", commonSettings.getUpdated_at());
			for (Gear gear : gearList) {
				JSONObject userJson = new JSONObject();
				userJson.put("gid", gear.getGid());
				userJson.put("weight", gear.getWeight());
				userJson.put("wheel_size", gear.getWheel_size());
				userJson.put("activated", gear.getActivated());
				userJson.put("name", gear.getName());
				userJson.put("type", gear.getType());
				jsonArray.put(userJson);
			}
			userProfileAllJson.put("gears", jsonArray);
			String gearsJsonStr = userProfileAllJson.toString();
			Log.d(TAG, "wangsm_bes,  gears json str: " + gearsJsonStr);
			return gearsJsonStr;
		} catch (JSONException e) {
			throw new RuntimeException(e);
		}
	}

	// create workouts.json string
	public static String createWorkoutsJsonStr(Workouts workouts) {
		JSONArray jsonArrayAll = new JSONArray();
		if (workouts == null) {
			Log.d(TAG, "workouts is null,return");
			return null;
		}

		try {
			JSONObject workoutsAllJson = new JSONObject();
			workoutsAllJson.put("list_version", workouts.getList_version());
			workoutsAllJson.put("need_update", workouts.getNeed_update());
			workoutsAllJson.put("version", workouts.getVersion());
			workoutsAllJson.put("device_model", workouts.getDevice_model());
			workoutsAllJson.put("sn", workouts.getSn());
			workoutsAllJson.put("update_at", workouts.getUpdate_at());
			workoutsAllJson.put("workouts_size", workouts.getWorkouts_size());
			List<Workout> workoutList = workouts.getWorkoutList();
			if (workoutList != null && workouts.getWorkouts_size() == 0 && !workoutList.isEmpty()) {
				workoutsAllJson.put("workouts_size", workoutList.size());
			}

			if (workouts.getWorkoutList() != null) {
				for (Workout workout : workouts.getWorkoutList()) {
					JSONArray jsonArray = new JSONArray();
					jsonArray.put(String.valueOf(workout.getTimestampInYHDHMS()));
					jsonArray.put(workout.getFileSize());
					// workout.setState(WorkoutState.Synced);
					jsonArray.put(workout.getState().getData());
					jsonArray.put(workout.getSport_type());
					jsonArray.put(workout.getDuration());
					jsonArray.put(workout.getDistance());
					jsonArray.put(workout.getTotal_calorie());
					jsonArray.put(workout.getAvg_speed());
					jsonArrayAll.put(jsonArray);
				}
			}
			workoutsAllJson.put("workouts", jsonArrayAll);
			String workoutsJsonStr = workoutsAllJson.toString();
			Log.d(TAG, "wangsm_bes,  the workout json str: " + workoutsJsonStr);
			return workoutsJsonStr;// gearsJsonStr;
		} catch (JSONException e) {
			throw new RuntimeException(e);
		}
	}

	public static boolean writeWorkoutsJsonStrToFile(Context context, String jsonStr, String jsonName) {
		boolean result = false;
		String modelName;
		String sn;

		if (jsonStr == null || context == null || jsonName == null) {
			Log.d(TAG, "the workouts params is null,return ");
			return result;
		}
		modelName = SettingsJsonUtils.getDeviceModel(context);
		sn = SettingsJsonUtils.getSn(context);
		if (modelName == null || sn == null) {
			Log.d(TAG, "pls provide the device model and sn.");
			return false;
		}

		String fileDirStr = FileUtils.checkExternalDirectoryPathExist(false, modelName, sn, SettingsJsonUtils.WORKOUTS_FOLDER);
		File settingsFile = new File(fileDirStr);
		Log.d(TAG, "settingsFile path:" + settingsFile.getAbsolutePath());
		File jsonFile = new File(settingsFile, jsonName);
		if (jsonFile.exists()) {
			boolean delReuslt = jsonFile.delete();
			if (!delReuslt) {
				Log.d("TAG", "delete workout json file fail");
				return result;
			}
		}
		try {
			boolean newFile = jsonFile.createNewFile();
			if (!newFile) {
				Log.d("TAG", "create workout json file fail");
				return result;
			}
		} catch (IOException exception) {
			exception.printStackTrace();
		}

		Log.d(TAG, "the jsonFileDir str: " + jsonFile.getAbsolutePath());
		result = writeJsonStrToFile(jsonStr, jsonFile);
		return result;
	}

	public static boolean writeSettingsJsonStrToFile(Context context, String modelName, String sn, String jsonStr, String jsonName) {
		boolean result = false;

		if (jsonStr == null || context == null || modelName == null || sn == null || jsonName == null) {
			Log.d(TAG, "the settings params is null,return ");
			return result;
		}
		String fileDirStr = FileUtils.checkExternalDirectoryPathExist(false, modelName, sn, SettingsJsonUtils.SETTINGS);
		File settingsFile = new File(fileDirStr);
		Log.d(TAG, "settingsFile path:" + settingsFile.getAbsolutePath());
		File jsonFile = new File(settingsFile, jsonName);
		if (jsonFile.exists()) {
			boolean delReuslt = jsonFile.delete();
			if (!delReuslt) {
				Log.d(TAG, "delete json file fail");
				return result;
			}
		}
		try {
			boolean newFile = jsonFile.createNewFile();
			if (!newFile) {
				Log.d(TAG, "create json file fail");
				return result;
			}
		} catch (IOException exception) {
			exception.printStackTrace();
		}

		Log.d(TAG, "the jsonFileDir str: " + jsonFile.getAbsolutePath());
		result = writeJsonStrToFile(jsonStr, jsonFile);
		return result;
	}

	public static boolean writeJsonStrToFile(String jsonString, String filePath) {
		boolean result = false;
		File jsonFile = new File(filePath);
		if (jsonFile.exists()) {
			result = jsonFile.delete();
			if (!result) {
				Log.d(TAG, "delete json file fail");
				return result;
			}
		}
		try {
			result = jsonFile.createNewFile();
			if (!result) {
				Log.d(TAG, "create json file fail");
				return result;
			}
		} catch (IOException exception) {
			exception.printStackTrace();
		}
		result = writeJsonStrToFile(jsonString, jsonFile);
		return result;
	}

	public static boolean writeJsonStrToFile(String jsonString, File jsonFile) {
		FileOutputStream fileOutputStream = null;
		if (jsonString == null || jsonFile == null || jsonFile.isDirectory()) {
			Log.d(TAG, " wangsm_bes, writeJsonStrToFile,file is error,return  ");
			return false;
		}
		Log.d(TAG, " wangsm_bes, writeJsonStrToFile,jsonString:  " + jsonString);
		if (!jsonFile.exists()) {
			boolean result = false;
			try {
				result = jsonFile.createNewFile();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			if (!result) {
				Log.d(TAG, "wangsm_bes, writeJsonStrToFile create file fail, the file is: " + jsonFile.getAbsolutePath());
				return false;
			}
		}
		try {
			fileOutputStream = new FileOutputStream(jsonFile, false);
			fileOutputStream.write(jsonString.getBytes(Charset.forName("UTF-8")));
			fileOutputStream.flush();
			Log.d(TAG, " wangsm_bes, writeJsonStrToFile,file write success ,path: " + jsonFile.getAbsolutePath());
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			if (fileOutputStream != null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}
		return true;
	}

	// add by wangsm for check Android\data\bb.lanxing\files\Lanxing\model_name\sn\Routebooks or Settings and so on.
	private static boolean ensureDirectoryExists(File dir) {

		/*
		 * if(dir != null && dir.isFile() && dir.exists()){ Log.d(TAG,"this is file ,return true,"+
		 * dir.getAbsolutePath()); return true; }
		 */
		if ((dir != null && dir.isDirectory() && dir.exists()) || dir.mkdirs()) {
			Log.d(TAG, "this is dir ,return true," + dir.getAbsolutePath());
			return true;
		}
		Log.d(TAG, "file or dir error,return false,");
		return false;
		// return (dir.exists() && dir.isDirectory()) || dir.mkdirs();
	}

	public static boolean ensureDirectoryExists(String dir) {
		return ensureDirectoryExists(new File(dir));
	}

	public static boolean ensureFileExists(String filePath) {
		return ensureFileExists(new File(filePath));
	}

	private static boolean ensureFileExists(File file) {
		Log.d(TAG, "ensureFileExists ,  file:" + file + ",file.isFile():" + file.isFile() + ",file.exists(): " + file.exists());
		if (file.isFile() && file.exists()) {
			Log.d(TAG, "this is file ,return true," + file.getAbsolutePath());
			return true;
		}
		Log.d(TAG, "file  error,return false,");
		return false;
	}

	public static String checkExternalDirectoryPathExist(boolean isFile, String... components) {
		StringBuilder sb = new StringBuilder();
		sb.append(App.getContext().getExternalFilesDir(null));
		sb.append(File.separatorChar);
		sb.append(DeepLinkPathConstants.SCHEME_APP_LANXING);
		for (String str2 : components) {
			sb.append(File.separatorChar);
			sb.append(str2);
		}
		String sb2 = sb.toString();
		Log.d(TAG, "check external dir path ,sb2," + sb2);

		if (isFile) {
			if (ensureFileExists(sb2)) {
				return sb2;
			}
		} else if (ensureDirectoryExists(sb2)) {
			return sb2;
		}
		Log.d(TAG, "the file or dir error,return null");
		return null;
	}

	/*
	 * add by wangsm for parse routebooks.json Android\data\bb.lanxing\files\Lanxing\Lanxing\123456\Routebooks
	 */
	public static void sendRouteBooksJsonFile(Context context, ProtocolPresenter protocolPresenter, List<String> filePathList) {
		if (context == null || protocolPresenter == null || filePathList == null || filePathList.isEmpty()) {
			Log.i(TAG, "sendRouteBooksJsonFile the context is null,return ");
			return;
		}
		String deviceModel = SettingsJsonUtils.getDeviceModel(context);
		String deviceSn = SettingsJsonUtils.getSn(context);
		protocolPresenter = ProtocolPresenter.getInstance();
		String extraPath = FileUtils.checkExternalDirectoryPathExist(true, deviceModel, deviceSn, SettingsJsonUtils.ROUTE_BOOKS_FOLDER, SettingsJsonUtils.ROUTE_BOOKS_JSON);
		Log.i(TAG, "sendRouteBooksJsonFile PATH: " + extraPath);
		String fileName = extraPath.substring(extraPath.lastIndexOf(File.separatorChar) + 1);
		Log.i(TAG, "fileName: " + fileName);
		byte[] pathElpo = ArrayUtil.toBytes(ArrayUtil.str2HexStr(extraPath));
		if (extraPath.contains(SettingsJsonUtils.ROUTE_BOOKS_JSON)) {
			SPHelper.putPreference(context, KEY_LUSHU_FILE_ID, fileName);
			protocolPresenter.sendDeveloperData(SYSTEM_TRANS_LUSHU_FILE, pathElpo);
		}
		protocolPresenter.saveLanXingRouteBooksFiles(context, filePathList);
	}

	public static void sendWorkoutListFile(Context context, ProtocolPresenter protocolPresenter) {
		if (context == null || protocolPresenter == null) {
			Log.i(TAG, "sendWorkoutListFile the context is null,return ");
			return;
		}
		String deviceModel = SettingsJsonUtils.getDeviceModel(context);
		String deviceSn = SettingsJsonUtils.getSn(context);
		protocolPresenter = ProtocolPresenter.getInstance();
		String extraPath = FileUtils.checkExternalDirectoryPathExist(true, deviceModel, deviceSn, SettingsJsonUtils.WORKOUTS_FOLDER, SettingsJsonUtils.WORKOUT_JSON);
		Log.i(TAG, "sendWorkoutListFile PATH: " + extraPath);
		if (extraPath != null) {
			String fileName = extraPath.substring(extraPath.lastIndexOf(File.separatorChar) + 1);
			Log.i(TAG, "fileName: " + fileName);
			byte[] pathWorkoutList = ArrayUtil.toBytes(ArrayUtil.str2HexStr(extraPath));
			if (extraPath.contains("workouts.json")) {
				SPHelper.putPreference(context, KEY_WORKOUT_LIST_FILE_ID, "workout.list");
				protocolPresenter.sendDeveloperData(SYSTEM_TRANS_WORKOUT_LIST_FILE, pathWorkoutList);
			}
		}
	}

	public static RouteBookInfo queryRouteBookInfoWithServerId(String serverId) {
		RouteBookInfo routeBookInfo = null;
		Log.d(TAG, "the routebook serverId is: " + serverId);
		List<RouteBookInfo> list = LitePal.where("serverId = ?", serverId).find(RouteBookInfo.class);
		Log.d(TAG, "list.size is: " + list.size());
		if (!list.isEmpty()) {
			routeBookInfo = list.get(0);
			Log.d(TAG, "the routebookinfo db exist,id: " + routeBookInfo.getId());
			routeBookInfo = LitePal.find(RouteBookInfo.class, routeBookInfo.getId());
		}
		return routeBookInfo;
	}

	// end by wangsm
	public static boolean createRouteBooks(Context context, List<Route> routes) {
		long updated_at = 1717569375L;
		String version = "2.0.0";

		if (context == null || routes == null || routes.isEmpty()) {
			Log.d(TAG, "parma is null,return");
			return false;
		}
		String deviceModel = SettingsJsonUtils.getDeviceModel(context);
		String deviceSn = SettingsJsonUtils.getSn(context);
		if (deviceModel == null || deviceSn == null) {
			Log.d(TAG, "pls provide the device model and sn.");
			return false;
		}

		String booksFolder = FileUtils.createRouteBooksFolder(deviceModel, deviceSn);
		Log.i(TAG, "createRouteBooks: result =  " + booksFolder);

		JSONArray jsonArray = new JSONArray();
		// JSONObject jsonObject = new JSONObject();
		try {
			for (Route route : routes) {
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("rid", route.getRid());
				jsonObject.put("source", route.getSource());
				jsonObject.put("name", route.getName());
				jsonObject.put("type", route.getType());
				jsonObject.put("version", route.getVersion());
				jsonObject.put("length", route.getLength());
				jsonObject.put("gain", route.getGain());
				jsonObject.put("ext", route.getExt());
				jsonArray.put(jsonObject);
			}
			boolean result = FileUtils.writeDataToRouteBooks(booksFolder, SettingsJsonUtils.ROUTE_BOOKS_JSON, deviceModel, deviceSn, version, updated_at, jsonArray);
			Log.i(TAG, "create routebook.json result =  " + result);
			return result;
		} catch (JSONException e) {
			e.printStackTrace();
		}

		return false;
	}

	public static Routebooks parseRouteBooksJson(Context context) {
		Routebooks routebooks = null;

		if (context == null) {
			Log.d(TAG, "context is null.return");
			return null;
		}

		String deviceModel = SettingsJsonUtils.getDeviceModel(context);
		String deviceSn = SettingsJsonUtils.getSn(context);
		if (deviceModel == null || deviceSn == null) {
			Log.d(TAG, "pls provide the device model and sn.");
			return null;
		}

		String fileDirStr = FileUtils.checkExternalDirectoryPathExist(true, deviceModel, deviceSn, SettingsJsonUtils.ROUTE_BOOKS_FOLDER, SettingsJsonUtils.ROUTE_BOOKS_JSON);
		bb.lanxing.util.Log.d(TAG, "the file dir: " + fileDirStr);
		if (fileDirStr != null) {
			routebooks = FileUtils.createRouteBooksFromFile(fileDirStr);
		}
		if (null != routebooks) {
			bb.lanxing.util.Log.d(TAG, "the route books info: " + routebooks.toString());
		}
		return routebooks;
	}

	public static Routebooks createRouteBooksFromFile(String str) {
		try {
			Gson gson = new Gson();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(str)));
			StringBuilder sb = new StringBuilder();
			while (true) {
				String readLine = bufferedReader.readLine();
				if (readLine != null) {
					sb.append(readLine);
				} else {
					String sb2 = sb.toString();
					return gson.fromJson(sb2, Routebooks.class);
				}
			}
		} catch (JsonParseException | IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String createRouteBooksFolder(String modelName, String sn) {
		return AppFileUtils.buildExternalDirectoryPath(modelName, sn, SettingsJsonUtils.ROUTE_BOOKS_FOLDER);
	}

	public static boolean writeDataToRouteBooks(String folder, String fileName, String modelName, String sn, String version, long updateTime, JSONArray jsonArray) {
		File file = new File(folder, fileName);
		boolean result = false;
		if (file.exists()) {
			result = file.delete();
		}
		try {
			result = file.createNewFile();
			if (!result) {
				return result;
			}
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("version", version);
			jsonObject.put("device_model", modelName);
			jsonObject.put("sn", sn);
			jsonObject.put("update_at", updateTime);
			if (null != jsonArray) {
				jsonObject.put("routes", jsonArray);
				Log.d(TAG, "the routebook jsonArray str: " + jsonArray.toString());
			}
			Log.d(TAG, "the routebook json str: " + jsonObject.toString());
			result = writeJsonStrToFile(jsonObject.toString(), file);
		} catch (IOException | JSONException exception) {
			exception.printStackTrace();
		}

		return result;
	}

	// add by wangsm for delete file
	public static boolean deleteFile(String filePath) {
		File file = null;
		boolean result = false;

		Log.d(TAG, "deleteFile, filePath: " + filePath);
		if (filePath == null) {
			return false;
		}
		file = new File(filePath);
		if (file.isFile()) {
			result = file.delete();
		}
		return result;
	}

	// add for auto sync time
	public static void sendCmdToSyncTime(ProtocolPresenter protocolPresenter, String deviceAddress) {

		if (deviceAddress == null || protocolPresenter == null) {
			Log.d(TAG, "parmas is null, return,not sync time");
			return;
		}
		int autoSync = SharedManager.getInstance().getTimeAutoSync(deviceAddress, TIME_AUTO_SYNC);

		Log.d(TAG, "sendCmdToSyncTime,autoSync value: " + autoSync);
		if (autoSync != TIME_AUTO_SYNC) {
			Log.d(TAG, "autoSync is false, return,not sync time");
			return;
		}
		protocolPresenter.sendInfoData(INFO_Set_Device_Time, null);
	}

	// end by wangsm
	public String getFilesDir(String path, String folder) {
		String dirPath = mContext.getExternalFilesDir("").getAbsolutePath() + "/" + folder + "/";
		createFolder(dirPath);
		String filePath = dirPath + path;
		return filePath;
	}

	public void initBinFile() {
		String path = mContext.getExternalFilesDir("").getAbsolutePath();
		String filePath = path + "/bin";
		File file = new File(filePath);
		if (!file.exists()) {
			file.mkdirs();
		}
	}

	public String getOtaFilePath() {
		String path = mContext.getExternalFilesDir("").getAbsolutePath();
		return path + "/bin";
	}

	public String getOtaZipFilePath() {
		String path = mContext.getExternalFilesDir("").getAbsolutePath();
		return path + "/bin/zip";
	}

	public String[] getOtaBinFileNames() {
		String path = mContext.getExternalFilesDir("").getAbsolutePath();
		String filePath = path + "/bin";
		File fatherFile = new File(filePath);
		File[] files = fatherFile.listFiles();
		if (files != null && files.length > 0) {
			String[] fileNames = new String[files.length];
			for (int i = 0; i < files.length; i++) {
				fileNames[i] = files[i].getName();
			}
			return fileNames;
		}
		return new String[0];
	}

	// add by wangs for write json file
	/*
	 * { "version": "2.0.0", "device_model": "A1", "sn": "795401", "update_at": 1717569375, "settings": {
	 * "language":"zh-cn", "unit":0, "temperature_unit":0, "time_formatter":0, "screen_on_mode":1, "auto_pause":0,
	 * "overwrite":0, "keytone":true } }
	 */

	public void saveBytesToFile(String path, String folder, byte[] data) {
		String filePath = getFilesDir(path, folder);
		File file = new File(filePath);
		BufferedOutputStream outStream = null;
		try {
			outStream = new BufferedOutputStream(new FileOutputStream(file, true));
			outStream.write(data);
			outStream.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != outStream) {
				try {
					outStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void createFolder(String path) {
		File fileDir = new File(path);
		boolean hasDir = fileDir.exists();
		if (!hasDir) {
			fileDir.mkdirs();// 这里创建的是目录
		}
	}

	public void HandleAnalyseFile(String info, String folderName, String fileName, String path) {
		// String filePath = getFolderPath()+"Android/"+ "data/"+ "com.bes.besall/"+ "files/";
		// isExist(filePath);
		// filePath = filePath + folderName +"/";
		// isExist(filePath);
		// filePath = filePath + fileName;
		// isExist(filePath);
		String filePath = getFilesDir(path, folderName);
		File file = new File(filePath);
		if (!file.exists()) {
			try {
				boolean newFile = file.createNewFile();
				FileOutputStream stream = new FileOutputStream(filePath, true);
				// String title = "Time,LEFT_AGC_1, LEFT_RSSI_1,LEFT_AGC_2, LEFT_RSSI_2,LEFT_AGC_3,
				// LEFT_RSSI_3,LEFT_RxGAIN,LEFT_TxGAIN,RIGHT_AGC_1, RIGHT_RSSI_1,RIGHT_AGC_2, RIGHT_RSSI_2,RIGHT_AGC_3,
				// RIGHT_RSSI_3,RIGHT_RxGAIN,RIGHT_TxGAIN"+ "\n";

				String title = "TIME,LEFT_PHONE_AGC, LEFT_PHONE_RSSI,LEFT_PHONE_MAX_RSSI,LEFT_PHONE_MIN_RSSI,LEFT_TWS_ARC,LEFT_TWS_RSSI,LEFT_TWS_MAX_RSSI,LEFT_TWS_MIN_RSSI,raw_rssi.ser,fa_idx_left,MIRROR_LEFT_PHONE_AGC,MIRROR_LEFT_PHONE_RSSI,MIRROR_LEFT_PHONE_MAX_RSSI,MIRROR_LEFT_PHONE_MIN_RSSI,RIGHT_PHONE_AGC,RIGHT_PHONE_RSSI,RIGHT_PHONE_MAX_RSSI,RIGHT_PHONE_MIN_RSSI,RIGHT_TWS_AGC,RIGHT_TWS_RSSI,RIGHT_TWS_MAX_RSSI,RIGHT_TWS_MIN_RSSI,peer_raw_rssi.ser,fa_idx_right,MIRROR_RIGHT_PHONE_AGC,MIRROR_RIGHT_PHONE_RSSI,MIRROR_RIGHT_PHONE_MAX_RSSI,MIRROR_RIGHT_PHONE_MIN_RSSI,CURRENT_ROLE" + "\n";
				// String title = "TIME,LEFT_PHONE_AGC,
				// LEFT_PHONE_RSSI,LEFT_PHONE_MAX_RSSI,LEFT_PHONE_MIN_RSSI,LEFT_TWS_ARC,LEFT_TWS_RSSI,LEFT_TWS_MAX_RSSI,LEFT_TWS_MIN_RSSI,raw_rssi.ser,RIGHT_PHONE_AGC,RIGHT_PHONE_RSSI,RIGHT_PHONE_MAX_RSSI,RIGHT_PHONE_MIN_RSSI,RIGHT_TWS_AGC,RIGHT_TWS_RSSI,RIGHT_TWS_MAX_RSSI,RIGHT_TWS_MIN_RSSI,peer_raw_rssi.ser,CRRENT_ROLE,extra_data
				// "+"\n";

				stream.write(title.getBytes("gbk"));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			FileOutputStream stream = new FileOutputStream(filePath, true);
			stream.write(info.getBytes("gbk"));
			stream.flush();
			stream.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public void RssiextendAnalyseFile(String info, String folderName, String fileName, String path) {
		// String filePath = getFolderPath()+"Android/"+ "data/"+ "com.bes.besall/"+ "files/";
		// isExist(filePath);
		// filePath = filePath + folderName +"/";
		// isExist(filePath);
		// filePath = filePath + fileName;
		// isExist(filePath);
		String filePath = getFilesDir(path, folderName);
		File file = new File(filePath);
		if (!file.exists()) {
			try {
				boolean newFile = file.createNewFile();
				FileOutputStream stream = new FileOutputStream(filePath, true);

				String title = "TIME,LEFT_PHONE_AGC, LEFT_PHONE_RSSI,LEFT_PHONE_MAX_RSSI,LEFT_PHONE_MIN_RSSI,LEFT_TWS_ARC,LEFT_TWS_RSSI,LEFT_TWS_MAX_RSSI,LEFT_TWS_MIN_RSSI,raw_rssi.ser,RIGHT_PHONE_AGC,RIGHT_PHONE_RSSI,RIGHT_PHONE_MAX_RSSI,RIGHT_PHONE_MIN_RSSI,RIGHT_TWS_AGC,RIGHT_TWS_RSSI,RIGHT_TWS_MAX_RSSI,RIGHT_TWS_MIN_RSSI,peer_raw_rssi.ser,CRRENT_ROLE,extra_data " + "\n";

				stream.write(title.getBytes("gbk"));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			FileOutputStream stream = new FileOutputStream(filePath, true);
			stream.write(info.getBytes("gbk"));
			stream.flush();
			stream.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public void HandleFileReport(String info, String folderName, String fileName, String path) {
		// String filePath = getFolderPath()+"Android/"+ "data/"+ "com.bes.besall/"+ "files/";
		// isExist(filePath);
		// filePath = filePath + folderName +"/";
		// isExist(filePath);
		// filePath = filePath + fileName;
		// isExist(filePath);
		String filePath = getFilesDir(path, folderName);
		File file = new File(filePath);
		if (!file.exists()) {
			try {
				boolean newFile = file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			FileOutputStream stream = new FileOutputStream(filePath, true);
			Log.e("info = ", info);
			stream.write(info.getBytes("gbk"));
			stream.flush();
			stream.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public void writeFlashContentfiles(String path, String folder, String info) {
		String filePath = getFilesDir(path, folder);
		File file = new File(filePath);
		try {
			if (!file.exists()) {
				file.createNewFile();
			}
			FileInputStream fis = new FileInputStream(file);
			long size = fis.available();
			fis.close();
		} catch (IOException e) {
			Log.e("ex", e.getMessage().toString());
		}
	}

	public static <T> T parseFromFile(String str, Class<T> t) {
		try {
			Gson gson = new GsonBuilder().create();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(str)));
			StringBuilder sb = new StringBuilder();
			while (true) {
				String readLine = bufferedReader.readLine();
				if (readLine != null) {
					sb.append(readLine);
				} else {
					String content = sb.toString().trim();
					Log.d(TAG, "parseFromFile content = " + content);
					return gson.fromJson(content, t);
				}
			}
		} catch (JsonParseException | IOException e) {
			e.printStackTrace();
			return null;
		}
	}
}
